﻿using System;
using System.IO;
using System.Text;
using System.Xml.Linq;

namespace MikroGui
{
    public class MatlabCommandLineAutomationConfig
    {
        #region Properties

        string _mainFuncPath = "";

        public string MainFuncPath
        {
            get { return _mainFuncPath; }
            set { _mainFuncPath = value; }
        }
        string _matlabExecutablePath = "";

        public string MatlabExecutablePath
        {
            get { return _matlabExecutablePath; }
            set { _matlabExecutablePath = value; }
        }
        string _ucsv = "";

        public string Ucsv
        {
            get { return _ucsv; }
            set { _ucsv = value; }
        }
        string _ycsv = "";

        public string Ycsv
        {
            get { return _ycsv; }
            set { _ycsv = value; }
        }
        string _outcsv = "";

        public string Outcsv
        {
            get { return _outcsv; }
            set { _outcsv = value; }
        }
        decimal _sampleTime = 2;

        public decimal SampleTime
        {
            get { return _sampleTime; }
            set { _sampleTime = value; }
        }
        decimal _delay = 1;

        public decimal Delay
        {
            get { return _delay; }
            set { _delay = value; }
        }

        #endregion

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Matlab path = ").AppendLine(MatlabExecutablePath)
                .Append("Matlab main function path = ").AppendLine(MainFuncPath)
                .Append("ucsv path = ").AppendLine(Ucsv)
                .Append("ycsv path = ").AppendLine(Ycsv)
                .Append("outcsv path = ").AppendLine(Outcsv)
                .Append("sample time = ").AppendLine(SampleTime.ToString())
                .Append("delay time = ").AppendLine(Delay.ToString());
            return sb.ToString();
        }

        public static MatlabCommandLineAutomationConfig Get()
        {
            XElement doc = XElement.Load(Directory.GetCurrentDirectory() + @"\MatlabComunicationConfig.xml");
            MatlabCommandLineAutomationConfig cfg = new MatlabCommandLineAutomationConfig();
            cfg.MatlabExecutablePath = doc.Element("matlabPath").Value;

            XElement mainFuncPath = doc.Element("matlabMainFunc");
            cfg.MainFuncPath = mainFuncPath.Element("path").Value;
            cfg.Ucsv = mainFuncPath.Element("param_ucsv").Element("value").Value;
            cfg.Ycsv = mainFuncPath.Element("param_ycsv").Element("value").Value;
            cfg.Outcsv = mainFuncPath.Element("param_ocsv").Element("value").Value;
            cfg.SampleTime = Convert.ToDecimal(mainFuncPath.Element("param_ts").Element("value").Value);
            cfg.Delay = Convert.ToDecimal(mainFuncPath.Element("param_delay").Element("value").Value);

            return cfg;
        }
    }

    public class MatlabCommandLineAutomation
    {
        #region Data
        string _matlabExecutablePath;
        string _matlabCommand;
        string _logFile;

        #endregion

        #region Interface

        public MatlabCommandLineAutomation(string matlabExecPath)
        {
            _matlabExecutablePath = matlabExecPath;
            _logFile = Directory.GetCurrentDirectory() + @"/matlab.log";
        }

        public string BuildShellCommand()
        {
            return GetMatlabExacutablePath() + GetMatlabStartArguments() + GetMatlabExecuteCommandArgument();
        }

        public string GetMatlabExecuteCommandArgument()
        {
            return " -r " + Utilities.DoubleQuoteString(_matlabCommand);
        }

        public string GetMatlabStartArguments()
        {
            return string.Format(" -nodesktop -nosplash -logfile {0}", Utilities.DoubleQuoteString(_logFile));
        }

        public string GetMatlabExacutablePath()
        {
            return _matlabExecutablePath;
        }

        public void AddCommand(string command)
        {
            _matlabCommand += command + "; ";
        }

        #endregion

        #region Commands

        public static string EstymujCommand(
            string yPath,
            string uPath,
            string oPath,
            string tsPath,
            string delayPath)
        {
            return new StringBuilder().Append("estymuj(")
                .Append(Utilities.SingleQuoteString(uPath)).Append(",")
                .Append(Utilities.SingleQuoteString(yPath)).Append(",")
                .Append(tsPath).Append(",")
                .Append(delayPath).Append(",")
                .Append(Utilities.SingleQuoteString(oPath)).Append(")")
                .ToString();
        }

        public static string EstymujCommand(
            string yPath,
            string uPath)
        {
            return EstymujCommand(yPath, uPath
                , Utilities.AddCurrentDirPathToFileName("out.csv")
                , "2"
                , "1"
                );
        }

        public static string ExitMatlabCommand()
        {
            return "exit";
        }


        public static string CurrentDirCommand(string directoryPath)
        {
            StringBuilder sb = new StringBuilder();
            return sb.Append("cd(").Append(Utilities.SingleQuoteString(directoryPath)).Append(")").ToString();
        }

        #endregion
        
        public static MatlabCommandLineAutomation GetDefault()
        {
            MatlabCommandLineAutomationConfig _cfg = MatlabCommandLineAutomationConfig.Get();
            MatlabCommandLineAutomation mb = new MatlabCommandLineAutomation(_cfg.MatlabExecutablePath);

            string matlabWorkingDir = Path.GetDirectoryName(_cfg.MainFuncPath);
            mb.AddCommand(CurrentDirCommand(matlabWorkingDir));

            string estumujCmd = EstymujCommand(
                Utilities.AddCurrentDirPathToFileName(_cfg.Ucsv),
                Utilities.AddCurrentDirPathToFileName(_cfg.Ycsv),
                Utilities.AddCurrentDirPathToFileName(_cfg.Outcsv),
                _cfg.SampleTime.ToString(),
                _cfg.Delay.ToString()
                );
            mb.AddCommand(estumujCmd);

            mb.AddCommand(ExitMatlabCommand());

            return mb; 
        }

        static void Test()
        {
            MatlabCommandLineAutomation mb = MatlabCommandLineAutomation.GetDefault();

            Console.WriteLine();
            Console.WriteLine("MATLAB EXEC PATH:");
            Console.WriteLine(mb.GetMatlabExacutablePath());
            Console.WriteLine();
            Console.WriteLine("MATLAB START ARGS:");
            Console.WriteLine(mb.GetMatlabStartArguments());
            Console.WriteLine();
            Console.WriteLine("MATLAB COMMAND TO EXECUTE ARG:");
            Console.WriteLine(mb.GetMatlabExecuteCommandArgument());
        }

    }




}
